package hello.word.m2.maven.support;

import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
//import lombok.NoArgsConstructor;
//import lombok.NonNull;
//import lombok.extern.slf4j.Slf4j;

import java.util.LinkedList;
import java.util.List;
import java.util.StringJoiner;

@SuppressWarnings("unused")
//@NoArgsConstructor
//@Slf4j
public final class DaoConditionChain {
	public DaoConditionChain() {
	}

	private final List<Item> linkedList = Lists.newLinkedList();

	public DaoConditionChain(/*@NonNull*/ Condition firstCondition) {
		linkedList.add(new Item(firstCondition));
	}

	public DaoConditionChain and(/*@NonNull*/ Condition condition) {
		if (linkedList.isEmpty()) {
			linkedList.add(new Item(condition));
		} else {
			linkedList.add(new Item("and", condition));
		}
		return this;
	}

	public DaoConditionChain or(/*@NonNull*/ Condition condition) {
		if (linkedList.isEmpty()) {
			linkedList.add(new Item(condition));
		} else {
			linkedList.add(new Item("or", condition));
		}
		return this;
	}

	public DaoConditionChain merge(/*@NonNull*/ DaoConditionChain other) {
		LinkedList<Item> o = Lists.newLinkedList(other.linkedList);
		o.set(0, new Item("and", o.get(0).condition));
		linkedList.addAll(o);
		return this;
	}

	String asString() {
		if (!linkedList.isEmpty()) {
			final StringBuilder sb = new StringBuilder();
			for (Item item : linkedList) {
				if (sb.length() == 0) {
					final String str = item.condition.asString().get();
					if (str != null) {
						sb.append(str);
					}
				} else {
					final String str = item.asString();
					if (str != null) {
						sb.append(" ").append(str);
					}
				}
			}
			return sb.toString();
		} else {
			return "";
		}
	}

	@Override
	public String toString() {
		return Joiner.on(" ").join(linkedList);
	}

	private static class Item {
		private final String logicalOperator;
		private final Condition condition;

		Item(Condition condition) {
			this("", condition);
		}

		Item(String logicalOperator, Condition condition) {
			this.logicalOperator = logicalOperator;
			this.condition = condition;
		}

		String asString() {
			return new StringJoiner(" ").add(logicalOperator).add(condition.asString().get()).toString();
		}

		@Override
		public String toString() {
			return logicalOperator + " " + condition.toString();
		}
	}
}